Я бачив багато захищених месанжерів, але всі вони написані людьми, які
занадто надихалися крипто-стартапами. Крипто-стартап — це така тєма
де ти вивчив як крутити чотири функції і думаєш шо готовий запропонувати
рішення рівня NSA. Але, як показав час, вижило не багато месенжерів.
Хочу виділити ті захищені месанжери та системи доставки повідомлень,
які вижили і досі є актуальними, а також розказати як я створюю свій месенжер.
IRC PGP OTR
Зараз вже відмирає потроху Freenode, як відмирає Reddit та Twitter,
але всі хто залишився в IRC перейшли в Libera.Chat,
по-справжньому осучаснений сервер з TLS та OTR плагіном. IRC — це взагалі
можна сказати перший месенжер в історії, а PGP — перший стандарт захищеного обміну повідомленнями.
PGP (RFC 4880) був розроблений в 1991 році Пилипом Цимерманом і в 2012 аж він став підтримувати ECDH (RFC 6637).
OTR, або Off-the-Record
на відміну від PGP немає стандарту і був придуманий лише в 2004 році, але активно підтримується
як плагін у багатьох месенжерах, в тому числі і для IRC.
XMPP OTR
Перший мій комерційний проект на Erlang був месенжер для малайзійської
державної компанії, де використовувася протокол XMPP та продукт ejabberd. В
XMPP світі широко та активно застосовується саме OTR плагін для захищеного
обміну повідомленнями, хоча я мало бачив людей хто цим реально користується.
E-MAIL SMTP PGP
Система доставки повідомлень є беззаперечно не тільки першим прото-месенжером,
але також і першою системою управління бізнес-процесами, тому ці поняття дуже сильно переплітаються.
Наприклад, якшо уявити шо в месенжері всі повідомлення від невідомих кореспондентів
попадають не в головний фід чатів, а в спецільних інбокс спочатку, а вже потім перенаправляються
в певну папку чатів (ростер), то цим можна трохи стерти границю відмінностей в клієнській
архітектурі між поштою та месенжерами. В SMTP світі домінуючим гравцем на ринку плагінів
до поштових клієнтів був до недавнього часу PGP.
Нестандартизовані месенжери
До цього класу можна віднести всі стартапи до яких є хоч трохи довіри, де можна
повністю скачати і клієнт і сервер і внести небходні зміни за потреби. Це, наприклад,
Signal, Session, Element. Всі інші, де ви не знаєте шо відбувається, назвати захищеними месенжерами
можна лише умовно: Telegram, WhatsApp, Threema, Wickr, Facebook, Skype, iMessages.
CMS S/MIME
Хвиля здорового глузду почала накривати захищені месенжери тільки з 1999 року,
коли вийшов перший RFC 2630 на синтаксис криптографічних повідомлень CMS.
Оскільки вся промислова криптографія базується на протоколах описаних в мові ASN.1
(а це небагато не мало стандарти на CA, X.509, PKI, всі види включів RSA і ECC,
LDAP, OCSP, TSP, а також ДСТУ стандарти захисту, такі як
Кваліфікований
Електронний Підпис), то логічно аби криптографічні
захищені повідомлення були частиною цього стандарту. Так і сталося. Текстова
версія протоколу CMS називається S/MIME і просто містить BASE64 тіло разом з заголовками,
що ідеально підходить до SMTP протоколу. Зараз CMS S/MIME підтримують майже всі промислові
поштові клієнти: Thunderbird, Outlook, Postbox, Evolution, MailMate, Nine, MailDroid, iOS Mail.
Я вважаю шо сучасний відкритий криптографічний месенжер побудований на державних
стандартах повинен базуватися на цій специфікації. І мій месанжер будується на ції специфікації
та орієнтується на неї.
Дешифрація CMS повідомлення
Аби продемонструвати технологію CMS, я покажу початок розробки референсного термінального (консольного) клієнта,
який буде основою для форків і майбутніх клієнтів на інших платформах. Заодно як ви вже розумієте
це буде демонстрацією безапеляційної переваги Erlang, який містить безкоштовний промисловий ASN.1
компілятор, що дозволяє генерувати код прямо з законів України та RFC стандартів.
Основи сучасної криптографії
Перед початком дамо основи сучасної криптографії в одному параграфі. Для створення спільного
секретного слова, яким можна було би шифрувати трафік за допомогою симетричного шифру AES
використовується математичний протокол обміну публічними ключами Діфі-Хелмана
і його обчислення на сторонах кореспондентів комунікації.
Суть протоколу зводиться до наступниїх рівнянь:
Два учасники мають пару Публічний та Приватний ключі, які генеруються
функціями puiblic та private, зазвичай приватний ключ
є псевдовипадковим числом певної розмірності, а публічний ключ
утворюється як похідний, який задовільняє умовам рівняння.
Існує також функція shared, яка дозволяє побудувати похідний
ключ по парі публічного та приватного ключів різних кореспондентів.
Якшо попарно схрестити ці дві пари через цю функцію, то отримані
ключі будуть співпадати — це називається протокол Діфі-Хелмана.
Кожна крипто-система на публічних та приватних ключа повинна
відповідати цим рівнянням.
Далі використовується симетричні алгоритми шифрування такі як AES в
різних флейворах CCM, GCM, ECB і т.д. Код на мові Erlang виглядає так:
На цьому можна було би зупинитись і почати писати псевдо-захищений
месенжер, як всі роблять, але тут дуже багато безпекових н'юансів
починаючи від IV педінгів, HKDF і AES-WRAP протоколів, і закінчуючи власне CMS.
Тому переходимо до наступного параграфу.
Генерація криптографічного повідомлення CMS
В цьому параграфі я розгляну зразу дві криптографічні системи на яких буду
тестувати код референсного клієнта мого месенжера. Перший — це класичний
OpenSSL клієнт openssl cms, а другий — це бібліотека pki.js.
І вже після них і всіх сумісних протоколі я перейду до поштових клієнтів
і їх підримки (чисто погратися).
Для генерації криптографічного повідомлення необхідно спочатку дві пари
ключів кореспондентів. Насправді ми тестуємо шифрування (без підпису),
тому достатньо пари — публічний ключ відправника, та приватний ключ
отримувача. В процесі підпису відправником створюється ефимерний приватний
ключ, а для розшифровування нам не потрібний публічний ключ отримувача, тому
шо він віддрукований в самому конверті криптогрфічного повідомлення, то ж
ми на стороні отримувача просто викликатимемо функцію shared (в JavaScript
називається deriveKey) і отримуватимемо спільний ключ яким і будемо розшифровувати.
Але перед цим треба створити сертифікати. Оскільки це тема окремої статті про
Центр Сертифікації Ключів, а в нас він є в складі месанжера і називається SYNRC CA,
то ми просто вікладемо цю статтю в стіл і покажемо просто як ним користуватися.
Ну або, якшо ви вмієте можете просто згенерувати їх за допомогою openssl,
детальний перевірений перелік команд необхідний для цього наведено в офіційній
документації по SYNRC CA — Як видавати ECC сертифікати.
Після описаних вище процедур у вас повинно з'явитися три файли: публічний, приватний
ключі та публічний ключ сертифікаційного центру.
Сертифікат ЦА caroot.pem
Публічний ключ кореспондента client.pem
Приватний ключ кореспондента client.key
Одразу після цього створюємо криптографічне повідомлення у форматі CMS S/MIME:
Перевіряємо працездатність самого openssl:
Дешифрація засобами Erlang
Як ви знаєте з попередніх статей, аби користуватися промислово криптографією потрібно
промислово згенерувати код ASN.1 компіляторм прямо з ASN.1 дефініцій. Для розшифровки CMS
нам знадобляться наступні дефініції:
Ці команди просто згенерують код на Erlang. Далі нам знадобиться
маленька прелюдія:
Це функції побудовані над стандартними з базової бібліотеки, які читають файли
обчислюють похідні ключі та формують спеціальну структуру ECC-CMS-Info в DER
кодуванні яка нам знадобить для дешифрації повідомлення.
Перший крок — це декодування текстового повідомлення в Erlang об'єкт зразу.
Тільки подивившись на цю структуру можна одразу все зрозуміти.
Далі справа CMS протоколу, який звучить наступним чином:
1) Визначте схему видачі ECC сертифікату PRIME256V1, SECP385R1, тощо;
2) Розпакуйте структуру EnvelopedData та знайдіть там наступні елементи:
публічний сертифікат отримувача publicKey, параметри ukm для
структури ECC-CMS-SharedInfo, спеціальний ключ encrypedKey який повинен
розпакуватися алгоритмом AES-WRAP, педінг-параметр для IV для AES шифрів,
та власне саме закодоване повідомлення або payload — data;
3) Сторіть похідний ключ sharedKey на основі публічного ключа кореспондента та вашого
приватного ключа з файлу client.key;
4) Застосуйте алгоритм KDF (Key Derive Function) для
подовження ключа sharedKey до необхідної довжини
використовуючи DER закодовану ECC-CMS-SharedInfo структуру ukm
з інформацією яка є в конверті;
5) Розпакуйте алгоритмом AES-UNWRAP закодований ключ encryptedKey
ключом kdf отриманим на попередньому кроці;
6) Розпакуйте payload data відповідним симетричним алгоритмом
використовуючи ключ отриманий на попередньому кроці та iv
параметр з конверту.
Це приклад є частиною SYNRC CA
та SYNRC CHAT які можна просто
скачати і подивитися маючи Elixir. Сертифікати pki.js закомічені в
CA, а openssl команди та сертифікати SYNRC CA закомічені в CHAT.
Успіхів в дешифрації, мамкіні криптографи на JavaScript!
Додаток А. Алгоритми
Додаток Б. Дефініції
Додаток В. Стандарти
CHAT X.509 використовує наступні стандарти та протоколи: